/*
 * jxSwing Project (2014)
 * 
 * by Denilson Edinaldo Pinto
 * 
 * LGPL
 * Copyright (C) 2014
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package org.jxSwing.component.panel;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.HeadlessException;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.net.URL;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.Collection;
import java.util.EventObject;
import java.util.List;

import javax.accessibility.AccessibleContext;
import javax.print.PrintService;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable.PrintMode;
import javax.swing.ListSelectionModel;
import javax.swing.RowSorter;
import javax.swing.UIManager;
import javax.swing.border.LineBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.RowSorterEvent;
import javax.swing.event.TableColumnModelEvent;
import javax.swing.event.TableModelEvent;
import javax.swing.plaf.TableUI;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;

import org.jxSwing.Cleanable;
import org.jxSwing.component.JXComponent;
import org.jxSwing.component.bar.FooterTableBar;
import org.jxSwing.component.bar.HeaderTableBar;
import org.jxSwing.component.table.BeanTable;
import org.jxSwing.component.table.BeanTableColumn;
import org.jxSwing.component.table.BeanTableModel;
import org.jxSwing.component.table.LineNumberTable;
import org.jxSwing.i18n.I18N;
import org.jxUtils.check.CheckUtil;
import org.jxUtils.collection.ListSet;
import org.jxUtils.enumeration.CSVSeparator;

import sun.awt.image.ImageFormatException;

/**
 * @author Denilson Edinaldo Pinto
 * @porject jxSwing
 * @package org.jxSwing.component.panel
 * @date 22/03/2014 - 17:10:20
 * @param <Bean>
 */
public class BeanTablePanel<Bean> extends JPanel implements JXComponent, Cleanable {
	
	private static final long serialVersionUID = 6600787252654136872L;
	
	private HeaderTableBar<Bean> headerBar;
	
	private JScrollPane scrollPane;
	
	private final BeanTable<Bean> table;
	
	private FooterTableBar footerBar;
	
	private boolean requiredBorderEnabled = true;
	
	/**
	 * @param bean
	 */
	public BeanTablePanel(final Bean bean) {
	
		table = new BeanTable<Bean>(bean);
		
		initGUI();
	}
	
	/**
	 * @param values
	 */
	public BeanTablePanel(final Bean[] values) {
	
		table = new BeanTable<Bean>(values);
		
		initGUI();
	}
	
	/**
	 * @param beanTableColumn
	 * @param values
	 */
	public BeanTablePanel(final BeanTableColumn beanTableColumn, final Bean[] values) {
	
		table = new BeanTable<Bean>(beanTableColumn, values);
		
		initGUI();
	}
	
	/**
	 * @param beanTableColumn
	 * @param values
	 */
	public BeanTablePanel(final BeanTableColumn beanTableColumn, final Collection<Bean> values) {
	
		table = new BeanTable<Bean>(beanTableColumn, values);
		
		initGUI();
	}
	
	/**
	 * @param model
	 */
	public BeanTablePanel(final BeanTableModel<?> model) {
	
		table = new BeanTable<Bean>(model);
		
		initGUI();
	}
	
	/**
	 * @param beanClass
	 */
	public BeanTablePanel(final Class<?> beanClass) {
	
		table = new BeanTable<Bean>(beanClass);
		
		initGUI();
	}
	
	/**
	 * @param values
	 */
	public BeanTablePanel(final Collection<Bean> values) {
	
		table = new BeanTable<Bean>(values);
		
		initGUI();
	}
	
	/**
	 * @param container
	 * @return {@link Image} or <b>null</b>
	 */
	public static final Image getOwnerWindowIcon(final Container container) {
	
		return BeanTable.getOwnerWindowIcon(container);
	}
	
	/**
	 *
	 */
	private void initGUI() {
	
		getTable().setRequiredBorderEnabled(false);
		
		setLayout(new BorderLayout());
		
		add(getHeaderBar(), BorderLayout.NORTH);
		add(getScrollPane(), BorderLayout.CENTER);
		add(getFooterBar(), BorderLayout.SOUTH);
	}
	
	/**
	 * @param aColumn
	 */
	public final void addColumn(final TableColumn aColumn) {
	
		getTable().addColumn(aColumn);
	}
	
	/**
	 * @param index0
	 * @param index1
	 */
	public final void addColumnSelectionInterval(final int index0, final int index1) {
	
		getTable().addColumnSelectionInterval(index0, index1);
	}
	
	/**
	 *
	 */
	public final void addNotifyBeanTable() {
	
		getTable().addNotify();
	}
	
	/**
	 * Inserts a new Bean in the last row of the table
	 * 
	 * @return last row index added or -1
	 */
	public final synchronized int addRow() {
	
		final int lastRowIndexAdded = getTable().addRow();
		
		configureNewRow();
		
		return lastRowIndexAdded;
	}

	/**
	 * 
	 */
	private void configureNewRow() {
	
		getHeaderBar().getBtnEdit().setEnabled(getSelectedRows().length > 0);
		getHeaderBar().getBtnRemove().setEnabled(getSelectedRows().length > 0);
		
		clearFilter();
		
		setAutoResizeColumns(getAutoResizeColumns());
	}
	
	/**
	 * Inserts bean in the last row of the table
	 * 
	 * @param bean
	 * @return last row index added
	 */
	public final synchronized int addRow(final Bean bean) {
	
		final int lastRowIndexAdded = getTable().addRow(bean);
		
		configureNewRow();
		
		return lastRowIndexAdded;
	}
	
	/**
	 * Inserts bean in rowIndex of the table
	 * 
	 * @param rowIndex
	 * @param bean
	 * @return last row index added
	 */
	public final synchronized int addRow(final int rowIndex, final Bean bean) {
	
		final int lastRowIndexAdded = getTable().addRow(rowIndex, bean);
		
		configureNewRow();
		
		return lastRowIndexAdded;
	}
	
	/**
	 * Inserts beans in rowIndex of the table
	 * 
	 * @param rowIndex
	 * @param bean
	 * @return last row index added
	 */
	public final synchronized int addRow(final int rowIndex, final Collection<Bean> beans) {
	
		final int lastRowIndexAdded = getTable().addRow(rowIndex, beans);
		
		configureNewRow();
		
		return lastRowIndexAdded;
	}
	
	/**
	 * Inserts a new Bean after rowIndex of the table
	 * 
	 * @return last row index added or -1
	 */
	public final synchronized int addRowAfter(final int rowIndex) {
	
		final int lastRowIndexAdded = getTable().addRowAfter(rowIndex);
		
		configureNewRow();
		
		return lastRowIndexAdded;
	}
	
	/**
	 * Inserts bean after rowIndex of the table
	 * 
	 * @param rowIndex
	 * @param bean
	 * @return last row index added
	 */
	public final synchronized int addRowAfter(final int rowIndex, final Bean bean) {
	
		final int lastRowIndexAdded = getTable().addRowAfter(rowIndex, bean);
		
		configureNewRow();
		
		return lastRowIndexAdded;
	}
	
	/**
	 * Inserts a new Bean before rowIndex of the table
	 * 
	 * @return last row index added or -1
	 */
	public final synchronized int addRowBefore(final int rowIndex) {
	
		final int lastRowIndexAdded = getTable().addRowBefore(rowIndex);
		
		configureNewRow();
		
		return lastRowIndexAdded;
	}
	
	/**
	 * Inserts bean before rowIndex of the table
	 * 
	 * @param rowIndex
	 * @param bean
	 * @return last row index added
	 */
	public final synchronized int addRowBefore(final int rowIndex, final Bean bean) {
	
		final int lastRowIndexAdded = getTable().addRowBefore(rowIndex, bean);
		
		configureNewRow();
		
		return lastRowIndexAdded;
	}
	
	/**
	 * @param beans
	 * @return last row index added or -1
	 */
	public final synchronized int addRows(final Bean[] beans) {
	
		final int lastRowIndexAdded = getTable().addRows(beans);
		
		configureNewRow();
		
		return lastRowIndexAdded;
	}
	
	/**
	 * @param beans
	 * @return last row index added or -1
	 */
	public final synchronized int addRows(final Collection<Bean> beans) {
	
		final int lastRowIndexAdded = getTable().addRows(beans);
		
		configureNewRow();
		
		return lastRowIndexAdded;
	}
	
	/**
	 * Inserts beans after rowIndex of the table
	 * 
	 * @param beans
	 * @return last row index added or -1
	 */
	public final synchronized int addRowsAfter(final int rowIndex, final Bean[] beans) {
	
		final int lastRowIndexAdded = getTable().addRowsAfter(rowIndex, beans);
		
		configureNewRow();
		
		return lastRowIndexAdded;
	}
	
	/**
	 * Inserts beans after rowIndex of the table
	 * 
	 * @param beans
	 * @return last row index added
	 */
	public final synchronized int addRowsAfter(final int rowIndex, final Collection<Bean> beans) {
	
		final int lastRowIndexAdded = getTable().addRowsAfter(rowIndex, beans);
		
		configureNewRow();
		
		return lastRowIndexAdded;
	}
	
	/**
	 * Inserts beans before rowIndex of the table
	 * 
	 * @param beans
	 * @return last row index added
	 */
	public final synchronized int addRowsBefore(final int rowIndex, final Bean[] beans) {
	
		final int lastRowIndexAdded = getTable().addRowsBefore(rowIndex, beans);
		
		configureNewRow();
		
		return lastRowIndexAdded;
	}
	
	/**
	 * Inserts beans before rowIndex of the table
	 * 
	 * @param beans
	 * @return last row index added
	 */
	public final synchronized int addRowsBefore(final int rowIndex, final Collection<Bean> beans) {
	
		final int lastRowIndexAdded = getTable().addRowsBefore(rowIndex, beans);
		
		configureNewRow();
		
		return lastRowIndexAdded;
	}
	
	/**
	 * @param index0
	 * @param index1
	 */
	public final void addRowSelectionInterval(final int index0, final int index1) {
	
		getTable().addRowSelectionInterval(index0, index1);
	}
	
	/**
	 * @param autoResizeColumns
	 */
	public final void autoResizeColumns(final boolean autoResizeColumns) {
	
		getTable().autoResizeColumns(autoResizeColumns);
	}
	
	/**
	 * @param rowIndex
	 * @param columnIndex
	 * @param toggle
	 * @param extend
	 */
	public final void changeSelection(final int rowIndex, final int columnIndex, final boolean toggle, final boolean extend) {
	
		getTable().changeSelection(rowIndex, columnIndex, toggle, extend);
	}
	
	@Override
	public final void clear() {
	
		getTable().clear();
		
		configureNewRow();
	}
	
	/**
	 *
	 */
	public final void clearFilter() {
	
		getTable().clearFilter();
		
		getFooterBar().setRows(getRows().size(), getRows().size());
		
		getHeaderBar().setVisibleClearFilter(false);
	}
	
	/**
	 *
	 */
	public final void clearSelection() {
	
		getTable().clearSelection();
	}
	
	/**
	 * @param tableColumnModelEvent
	 */
	public final void columnAdded(final TableColumnModelEvent tableColumnModelEvent) {
	
		getTable().columnAdded(tableColumnModelEvent);
	}
	
	/**
	 * @param point
	 * @return the index of the column that point lies in, or -1 if the result is not in the range [0, getColumnCount()-1]
	 */
	public final int columnAtPoint(final Point point) {
	
		return getTable().columnAtPoint(point);
	}
	
	/**
	 * @param changeEvent
	 */
	public final void columnMarginChanged(final ChangeEvent changeEvent) {
	
		getTable().columnMarginChanged(changeEvent);
	}
	
	/**
	 * @param tableColumnModelEvent
	 */
	public final void columnMoved(final TableColumnModelEvent tableColumnModelEvent) {
	
		getTable().columnMoved(tableColumnModelEvent);
	}
	
	/**
	 * @param tableColumnModelEvent
	 */
	public final void columnRemoved(final TableColumnModelEvent tableColumnModelEvent) {
	
		getTable().columnRemoved(tableColumnModelEvent);
	}
	
	/**
	 * @param listSelectionEvent
	 */
	public final void columnSelectionChanged(final ListSelectionEvent listSelectionEvent) {
	
		getTable().columnSelectionChanged(listSelectionEvent);
	}
	
	/**
	 * @param viewColumnIndex
	 * @return the index of the corresponding column in the model
	 */
	public final int convertColumnIndexToModel(final int viewColumnIndex) {
	
		return getTable().convertColumnIndexToModel(viewColumnIndex);
	}
	
	/**
	 * @param modelColumnIndex
	 * @return the index of the corresponding column in the view
	 */
	public final int convertColumnIndexToView(final int modelColumnIndex) {
	
		return getTable().convertColumnIndexToView(modelColumnIndex);
	}
	
	/**
	 * @param viewRowIndex
	 * @return the index of the corresponding row in the model
	 */
	public final int convertRowIndexToModel(final int viewRowIndex) {
	
		return getTable().convertRowIndexToModel(viewRowIndex);
	}
	
	/**
	 * @param modelRowIndex
	 * @return the index of the corresponding row in the view, or -1 if the row isn't visible
	 */
	public final int convertRowIndexToView(final int modelRowIndex) {
	
		return getTable().convertRowIndexToView(modelRowIndex);
	}
	
	/**
	 *
	 */
	public final void createDefaultColumnsFromModel() {
	
		getTable().createDefaultColumnsFromModel();
	}
	
	/**
	 *
	 */
	public final void doLayoutBeanTable() {
	
		getTable().doLayout();
	}
	
	/**
	 * @param row
	 * @param column
	 * @return false if for any reason the cell cannot be edited, or if the indices are invalid
	 */
	public final boolean editCellAt(final int row, final int column) {
	
		return getTable().editCellAt(row, column);
	}
	
	/**
	 * @param row
	 * @param column
	 * @param eventObject
	 * @return false if for any reason the cell cannot be edited, or if the indices are invalid
	 */
	public final boolean editCellAt(final int row, final int column, final EventObject eventObject) {
	
		return getTable().editCellAt(row, column, eventObject);
	}
	
	/**
	 * @param changeEvent
	 */
	public final void editingCanceled(final ChangeEvent changeEvent) {
	
		getTable().editingCanceled(changeEvent);
	}
	
	/**
	 * @param changeEvent
	 */
	public final void editingStopped(final ChangeEvent changeEvent) {
	
		getTable().editingStopped(changeEvent);
	}
	
	/**
	 * @param regex
	 * @param caseSensitive
	 * @param columns
	 * @return resultCount
	 */
	public final int filter(final String regex, final boolean caseSensitive, final int... columns) {
	
		final int resultCount = getTable().filter(regex, caseSensitive, columns);
		
		getFooterBar().setRows(resultCount, getRows().size());
		
		getHeaderBar().setVisibleClearFilter(resultCount < getRows().size());
		
		return resultCount;
	}
	
	/**
	 * @param csvFile
	 * @param separator
	 * @throws IOException
	 */
	public final void fromCSV(final File csvFile, final CSVSeparator separator) throws IOException {
	
		getTable().fromCSV(csvFile, separator);
		
		clearFilter();
	}
	
	/**
	 * @param csvLines
	 * @param separator
	 * @throws IOException
	 */
	public final void fromCSV(final List<String> csvLines, final CSVSeparator separator) throws IOException {
	
		getTable().fromCSV(csvLines, separator);
		
		clearFilter();
	}
	
	/**
	 * @param csvString
	 * @param separator
	 * @throws IOException
	 */
	public final void fromCSV(final String csvString, final CSVSeparator separator) throws IOException {
	
		getTable().fromCSV(csvString, separator);
		
		clearFilter();
	}
	
	/**
	 * @param file
	 * @throws IOException
	 */
	public final void fromJSON(final File file) throws IOException {
	
		getTable().fromJSON(file);
	}
	
	/**
	 * @param file
	 * @throws IOException
	 */
	public final void fromXML(final File file) throws IOException {
	
		getTable().fromXML(file);
	}
	
	/**
	 * @param xmlStream
	 * @throws IOException
	 */
	public final void fromXML(final InputStream xmlStream) throws IOException {
	
		getTable().fromXML(xmlStream);
	}
	
	/**
	 * @param reader
	 * @throws IOException
	 */
	public final void fromXML(final Reader reader) throws IOException {
	
		getTable().fromXML(reader);
	}
	
	/**
	 * @param xml
	 * @throws IOException
	 */
	public final void fromXML(final String xml) throws IOException {
	
		getTable().fromXML(xml);
	}
	
	/**
	 * @param url
	 * @throws IOException
	 */
	public final void fromXML(final URL url) throws IOException {
	
		getTable().fromXML(url);
	}
	
	/**
	 * @return an AccessibleJTable that serves as the AccessibleContext of this BeanTable
	 */
	public final AccessibleContext getAccessibleContextBeanTable() {
	
		return getTable().getAccessibleContext();
	}
	
	/**
	 * @return the autoCreateColumnsFromModel of the table
	 */
	public final boolean getAutoCreateColumnsFromModel() {
	
		return getTable().getAutoCreateColumnsFromModel();
	}
	
	/**
	 * @return true if a RowSorter should be created when the model changes
	 */
	public final boolean getAutoCreateRowSorter() {
	
		return getTable().getAutoCreateRowSorter();
	}
	
	/**
	 * @return the autoResizeMode of the table
	 */
	public final int getAutoResizeMode() {
	
		return getTable().getAutoResizeMode();
	}
	
	/**
	 * @param rowIndex
	 * @return bean
	 */
	public final Bean getBean(final int rowIndex) {
	
		return getTable().getBean(rowIndex);
	}
	
	/**
	 * @return the TableCellEditor that does the editing, or null if the table is not currently editing.
	 */
	public final TableCellEditor getCellEditor() {
	
		return getTable().getCellEditor();
	}
	
	/**
	 * @param row
	 * @param column
	 * @return the editor for this cell; if null return the default editor for this type of cell
	 */
	public final TableCellEditor getCellEditor(final int row, final int column) {
	
		return getTable().getCellEditor(row, column);
	}
	
	/**
	 * @param row
	 * @param column
	 * @param includeSpacing
	 * @return the rectangle containing the cell at location row,column
	 */
	public final Rectangle getCellRect(final int row, final int column, final boolean includeSpacing) {
	
		return getTable().getCellRect(row, column, includeSpacing);
	}
	
	/**
	 * @param row
	 * @param column
	 * @return the assigned renderer; if null returns the default renderer for this type of object
	 */
	public final TableCellRenderer getCellRenderer(final int row, final int column) {
	
		return getTable().getCellRenderer(row, column);
	}
	
	/**
	 * @return true if both row and column selection models are enabled
	 */
	public final boolean getCellSelectionEnabled() {
	
		return getTable().getCellSelectionEnabled();
	}
	
	/**
	 * @param columnIndex
	 * @return column or null
	 */
	public final BeanTableColumn getColumn(final int columnIndex) {
	
		return getTable().getColumn(columnIndex);
	}
	
	/**
	 * @param identifier
	 * @return the TableColumn object that matches the identifier
	 */
	public final TableColumn getColumn(final Object identifier) {
	
		return getTable().getColumn(identifier);
	}
	
	/**
	 * @param columnIndex
	 * @return alias
	 */
	public final String getColumnAlias(final int columnIndex) {
	
		return getTable().getColumnAlias(columnIndex);
	}
	
	/**
	 * @param columnName
	 * @return alias
	 */
	public final String getColumnAlias(final String columnName) {
	
		return getTable().getColumnAlias(columnName);
	}
	
	/**
	 * @param columnAlias
	 * @return column or null
	 */
	public final BeanTableColumn getColumnByAlias(final String columnAlias) {
	
		return getTable().getColumnByAlias(columnAlias);
	}
	
	/**
	 * @param columnName
	 * @return column or null
	 */
	public final BeanTableColumn getColumnByName(final String columnName) {
	
		return getTable().getColumnByName(columnName);
	}
	
	/**
	 * @param column
	 * @return the type of the column at position column in the view where the first column is column 0
	 */
	public final Class<?> getColumnClass(final int column) {
	
		return getTable().getColumnClass(column);
	}
	
	/**
	 * @return the number of columns in the table
	 */
	public final int getColumnCount() {
	
		return getTable().getColumnCount();
	}
	
	/**
	 * @param columnName
	 * @return index
	 */
	public final int getColumnIndex(final String columnName) {
	
		return getTable().getColumnIndex(columnName);
	}
	
	/**
	 * @param columnIndex
	 * @return the Max Width
	 */
	public final int getColumnMaxWidth(final int columnIndex) {
	
		return getTable().getColumnMaxWidth(columnIndex);
	}
	
	/**
	 * @param columnIndex
	 * @return the Min Width
	 */
	public final int getColumnMinWidth(final int columnIndex) {
	
		return getTable().getColumnMinWidth(columnIndex);
	}
	
	/**
	 * @return the columnModel
	 */
	public final DefaultTableColumnModel getColumnModel() {
	
		return getTable().getColumnModel();
	}
	
	/**
	 * @param column
	 * @return the name of the column at position column in the view where the first column is column 0
	 */
	public final String getColumnName(final int column) {
	
		return getTable().getColumnName(column);
	}
	
	/**
	 * @param columnAlias
	 * @return a string containing the name of <code>column</code>
	 */
	public final String getColumnName(final String columnAlias) {
	
		return getTable().getColumnName(columnAlias);
	}
	
	/**
	 * @param columnIndex
	 * @return the Preferred Width
	 */
	public final int getColumnPreferredWidth(final int columnIndex) {
	
		return getTable().getColumnPreferredWidth(columnIndex);
	}
	
	/**
	 * @return the columns
	 */
	public final ListSet<BeanTableColumn> getColumns() {
	
		return getTable().getColumns();
	}
	
	/**
	 * @return the columns classes
	 */
	public final List<Class<?>> getColumnsClasses() {
	
		return getTable().getColumnsClasses();
	}
	
	/**
	 * @return true if columns can be selected, otherwise false
	 */
	public final boolean getColumnSelectionAllowed() {
	
		return getTable().getColumnSelectionAllowed();
	}
	
	/**
	 * @param columnIndex
	 * @return column values
	 */
	public final List<Object> getColumnValues(final int columnIndex) {
	
		return getTable().getColumnValues(columnIndex);
	}
	
	/**
	 * @param columnAlias
	 * @return column values
	 */
	public final List<Object> getColumnValuesByAlias(final String columnAlias) {
	
		return getTable().getColumnValuesByAlias(columnAlias);
	}
	
	/**
	 * @param columnName
	 * @return column values
	 */
	public final List<Object> getColumnValuesByName(final String columnName) {
	
		return getTable().getColumnValuesByName(columnName);
	}
	
	/**
	 * @param columnIndex
	 * @return the Width
	 */
	public final int getColumnWidth(final int columnIndex) {
	
		return getTable().getColumnWidth(columnIndex);
	}
	
	/**
	 * @param columnClass
	 * @return the default cell editor to be used for this columnClass
	 */
	public final TableCellEditor getDefaultEditor(final Class<?> columnClass) {
	
		return getTable().getDefaultEditor(columnClass);
	}
	
	/**
	 * @param columnClass
	 * @return the renderer for this columnClass
	 */
	public final TableCellRenderer getDefaultRenderer(final Class<?> columnClass) {
	
		return getTable().getDefaultRenderer(columnClass);
	}
	
	/**
	 * @return the value of the dragEnabled property
	 */
	public final boolean getDragEnabled() {
	
		return getTable().getDragEnabled();
	}
	
	/**
	 * @return the index of the column that contains the cell currently being edited; returns -1 if nothing being edited
	 */
	public final int getEditingColumn() {
	
		return getTable().getEditingColumn();
	}
	
	/**
	 * @return the index of the row that contains the cell currently being edited; returns -1 if nothing being edited
	 */
	public final int getEditingRow() {
	
		return getTable().getEditingRow();
	}
	
	/**
	 * @return Component handling editing session
	 */
	public final Component getEditorComponent() {
	
		return getTable().getEditorComponent();
	}
	
	/**
	 * @return whether or not this table is always made large enough to fill the height of an enclosing viewport
	 */
	public final boolean getFillsViewportHeight() {
	
		return getTable().getFillsViewportHeight();
	}
	
	/**
	 * @return the First Bean
	 */
	public final Bean getFirstBean() {
	
		return getTable().getFirstBean();
	}
	
	/**
	 * @return the First Bean
	 */
	public final Bean getFirstRow() {
	
		return getTable().getFirstRow();
	}
	
	/**
	 * @return the footerBar
	 */
	public final FooterTableBar getFooterBar() {
	
		if(footerBar == null) {
			footerBar = new FooterTableBar(getTable());
		}
		return footerBar;
	}
	
	/**
	 * @return the color used to draw grid lines
	 */
	public final Color getGridColor() {
	
		return getTable().getGridColor();
	}
	
	/**
	 * @return the headerBar
	 */
	public final HeaderTableBar<Bean> getHeaderBar() {
	
		if(headerBar == null) {
			headerBar = new HeaderTableBar<>(this);
		}
		return headerBar;
	}
	
	@Override
	public final int getIndex() {
	
		return getTable().getIndex();
	}
	
	/**
	 * @return the horizontal and vertical spacing between cells
	 */
	public final Dimension getIntercellSpacing() {
	
		return getTable().getIntercellSpacing();
	}
	
	/**
	 * @return the Last Bean
	 */
	public final Bean getLastBean() {
	
		return getTable().getLastBean();
	}
	
	/**
	 * @return the Last Bean
	 */
	public final Bean getLastRow() {
	
		return getTable().getLastRow();
	}
	
	/**
	 * @return last row index
	 */
	public final int getLastRowIndex() {
	
		return getTable().getLastRowIndex();
	}
	
	/**
	 * @return the lastSelectedRow
	 */
	public final int getLastSelectedRow() {
	
		return getTable().getLastSelectedRow();
	}
	
	/**
	 * @return the BeanTableModel that provides the data displayed by this BeanTable
	 */
	public final BeanTableModel<Bean> getModel() {
	
		return getTable().getModel();
	}
	
	/**
	 * @param table
	 * @return {@link Image} or <b>null</b>
	 */
	public final Image getOwnerWindowIcon() {
	
		return getTable().getOwnerWindowIcon();
	}
	
	/**
	 * @return a Printable for printing this JTable
	 */
	public final Dimension getPreferredScrollableViewportSize() {
	
		return getTable().getPreferredScrollableViewportSize();
	}
	
	/**
	 * @param printMode
	 * @param headerFormat
	 * @param footerFormat
	 * @return
	 */
	public final Printable getPrintable(final PrintMode printMode, final MessageFormat headerFormat, final MessageFormat footerFormat) {
	
		return getTable().getPrintable(printMode, headerFormat, footerFormat);
	}
	
	/**
	 * @param rowIndex
	 * @return bean
	 */
	public final Bean getRow(final int rowIndex) {
	
		return getTable().getRow(rowIndex);
	}
	
	/**
	 * @return the number of rows
	 */
	public final int getRowCount() {
	
		return getTable().getRowCount();
	}
	
	/**
	 * @return the height in pixels of a table row
	 */
	public final int getRowHeight() {
	
		return getTable().getRowHeight();
	}
	
	/**
	 * @param row
	 * @return the height, in pixels, of the cells in the row
	 */
	public final int getRowHeight(final int row) {
	
		return getTable().getRowHeight(row);
	}
	
	/**
	 * @return the number of pixels between cells in a row
	 */
	public final int getRowMargin() {
	
		return getTable().getRowMargin();
	}
	
	/**
	 * @return the rows
	 */
	public final List<Bean> getRows() {
	
		return getTable().getRows();
	}
	
	/**
	 * @return true if rows can be selected, otherwise false
	 */
	public final boolean getRowSelectionAllowed() {
	
		return getTable().getRowSelectionAllowed();
	}
	
	/**
	 * @return the object responsible for sorting
	 */
	public final TableRowSorter<? extends TableModel> getRowSorter() {
	
		return getTable().getRowSorter();
	}
	
	/**
	 * @param visibleRect
	 * @param orientation
	 * @param direction
	 * @return visibleRect.height or visibleRect.width per the orientation
	 */
	public final int getScrollableBlockIncrement(final Rectangle visibleRect, final int orientation, final int direction) {
	
		return getTable().getScrollableBlockIncrement(visibleRect, orientation, direction);
	}
	
	/**
	 * @return false unless getFillsViewportHeight is true and the table needs to be stretched to fill the viewport
	 */
	public final boolean getScrollableTracksViewportHeight() {
	
		return getTable().getScrollableTracksViewportHeight();
	}
	
	/**
	 * @return false if autoResizeMode is set to AUTO_RESIZE_OFF, otherwise returns true
	 */
	public final boolean getScrollableTracksViewportWidth() {
	
		return getTable().getScrollableTracksViewportWidth();
	}
	
	/**
	 * @param visibleRect
	 * @param orientation
	 * @param direction
	 * @return the "unit" increment for scrolling in the specified direction
	 */
	public final int getScrollableUnitIncrement(final Rectangle visibleRect, final int orientation, final int direction) {
	
		return getTable().getScrollableUnitIncrement(visibleRect, orientation, direction);
	}
	
	/**
	 * @return the scrollPane
	 */
	public final JScrollPane getScrollPane() {
	
		if(scrollPane == null) {
			scrollPane = new JScrollPane(getTable());
			scrollPane.setRowHeaderView(new LineNumberTable(scrollPane, getTable()));
		}
		return scrollPane;
	}
	
	/**
	 * @return selected bean
	 */
	public final Bean getSelectedBean() {
	
		return getTable().getSelectedBean();
	}
	
	/**
	 * @return selected beans
	 */
	public final List<Bean> getSelectedBeans() {
	
		return getTable().getSelectedBeans();
	}
	
	/**
	 * @return the index of the first selected column
	 */
	public final int getSelectedColumn() {
	
		return getTable().getSelectedColumn();
	}
	
	/**
	 * @return the number of selected columns, 0 if no columns are selected
	 */
	public final int getSelectedColumnCount() {
	
		return getTable().getSelectedColumnCount();
	}
	
	/**
	 * @return an array of integers containing the indices of all selected columns, or an empty array if no column is selected
	 */
	public final int[] getSelectedColumns() {
	
		return getTable().getSelectedColumns();
	}
	
	/**
	 * @return the index of the first selected row
	 */
	public final int getSelectedRow() {
	
		return getTable().getSelectedRow();
	}
	
	/**
	 * @return the number of selected rows, 0 if no rows are selected
	 */
	public final int getSelectedRowCount() {
	
		return getTable().getSelectedRowCount();
	}
	
	/**
	 * @return an array of integers containing the indices of all selected rows, or an empty array if no row is selected
	 */
	public final int[] getSelectedRows() {
	
		return getTable().getSelectedRows();
	}
	
	/**
	 * @return the Color object for the foreground property
	 */
	public final Color getSelectionBackground() {
	
		return getTable().getSelectionBackground();
	}
	
	/**
	 * @return the Color object for the foreground property
	 */
	public final Color getSelectionForeground() {
	
		return getTable().getSelectionForeground();
	}
	
	/**
	 * @return the object that provides row selection state, null if row selection is not allowed
	 */
	public final ListSelectionModel getSelectionModel() {
	
		return getTable().getSelectionModel();
	}
	
	/**
	 * @return true if the table draws horizontal lines between cells, false if it doesn't
	 */
	public final boolean getShowHorizontalLines() {
	
		return getTable().getShowHorizontalLines();
	}
	
	/**
	 * @return true if the table draws vertical lines between cells, false if it doesn't
	 */
	public final boolean getShowVerticalLines() {
	
		return getTable().getShowVerticalLines();
	}
	
	/**
	 * @return true if the editor should get the focus when keystrokes cause the editor to be activated
	 */
	public final boolean getSurrendersFocusOnKeystroke() {
	
		return getTable().getSurrendersFocusOnKeystroke();
	}
	
	/**
	 * @return the table
	 */
	public final BeanTable<Bean> getTable() {
	
		return table;
	}
	
	/**
	 * @return the tableHeader used by this table
	 */
	public final JTableHeader getTableHeader() {
	
		return getTable().getTableHeader();
	}
	
	/**
	 * @return the table title
	 */
	public final String getTitle() {
	
		return getHeaderBar().getTitle();
	}
	
	/**
	 * @return beanTable ToolTipText
	 */
	@Override
	public final String getToolTipText(final MouseEvent event) {
	
		return getTable().getToolTipText(event);
	}
	
	/**
	 * @return the TableUI object that renders this component
	 */
	public final TableUI getUIBeanTable() {
	
		return getTable().getUI();
	}
	
	/**
	 * @return whether to update the selection on a sort
	 */
	public final boolean getUpdateSelectionOnSort() {
	
		return getTable().getUpdateSelectionOnSort();
	}
	
	/**
	 * @param row
	 * @param column
	 * @return the Object at the specified cell
	 */
	public final Object getValueAt(final int row, final int column) {
	
		return getTable().getValueAt(row, column);
	}
	
	/**
	 * @param row
	 * @param columnName
	 * @return the Object at the specified cell
	 */
	public final Object getValueAt(final int row, final String columnName) {
	
		return getTable().getValueAt(row, columnName);
	}
	
	/**
	 * @return the number of visible columns in the table
	 */
	public final int getVisibleColumnCount() {
	
		return getTable().getVisibleColumnCount();
	}
	
	/**
	 * @return the visible columns
	 */
	public final ListSet<BeanTableColumn> getVisibleColumns() {
	
		return getTable().getVisibleColumns();
	}
	
	/**
	 * @return the acceptDuplicateRows
	 */
	public final boolean isAcceptDuplicateRows() {
	
		return getModel().isAcceptDuplicateRows();
	}
	
	@Override
	public boolean isAtributte() {
	
		return getTable().isAtributte();
	}
	
	/**
	 * @param row
	 * @param column
	 * @return true if the cell is editable
	 */
	public final boolean isCellEditable(final int row, final int column) {
	
		return getTable().isCellEditable(row, column);
	}
	
	/**
	 * @param row
	 * @param column
	 * @return true if row and column are valid indices and the cell at index (row, column) is selected, where the first row and first column are at index 0
	 */
	public final boolean isCellSelected(final int row, final int column) {
	
		return getTable().isCellSelected(row, column);
	}
	
	/**
	 * @param columnIndex
	 * @return column is editable
	 */
	public final boolean isColumnEditable(final int columnIndex) {
	
		return getTable().isColumnEditable(columnIndex);
	}
	
	/**
	 * @param column
	 * @return true if column is a valid index and the column at that index is selected (where 0 is the first column)
	 */
	public final boolean isColumnSelected(final int column) {
	
		return getTable().isColumnSelected(column);
	}
	
	/**
	 * @return true if the table is editing a cell
	 */
	public final boolean isEditing() {
	
		return getTable().isEditing();
	}
	
	/**
	 * @return true if {@code getRowCount() == 0}
	 */
	public final boolean isEmpty() {
	
		return getTable().isEmpty();
	}
	
	/**
	 * @return true if Add Button is enabled
	 */
	public final boolean isEnabledAdd() {
	
		return getHeaderBar().isEnabledAdd();
	}
	
	/**
	 * @return true if Auto Resize Columns Button is enabled
	 */
	public final boolean isEnabledAutoResizeColumns() {
	
		return getHeaderBar().isEnabledAutoResizeColumns();
	}
	
	/**
	 * @return true if CRUD Buttons is enabled
	 */
	public final boolean isEnabledCrudButtons() {
	
		return getHeaderBar().getBtnAdd().isEnabled();
	}
	
	/**
	 * @return true if Export Button is enabled
	 */
	public final boolean isEnabledExport() {
	
		return getHeaderBar().isEnabledExport();
	}
	
	/**
	 * @return true if Filter Button is enabled
	 */
	public final boolean isEnabledFilter() {
	
		return getHeaderBar().isEnabledFilter();
	}
	
	/**
	 * @return true if Print Button is enabled
	 */
	public final boolean isEnabledPrint() {
	
		return getHeaderBar().isEnabledPrint();
	}
	
	/**
	 * @return the locked
	 */
	public final boolean isLocked() {
	
		return getTable().isLocked();
	}
	
	@Override
	public final boolean isRequired() {
	
		return getTable().isRequired();
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see org.jxSwing.component.JXComponent#isRequiredBorderEnabled()
	 */
	@Override
	public boolean isRequiredBorderEnabled() {
	
		return requiredBorderEnabled;
	}
	
	/**
	 * @param rowIndex
	 * @return row is editable
	 */
	public final boolean isRowEditable(final int rowIndex) {
	
		return getModel().isRowEditable(rowIndex);
	}
	
	/**
	 * @param row
	 * @return true if row is a valid index and the row at that index is selected (where 0 is the first row)
	 */
	public final boolean isRowSelected(final int row) {
	
		return getTable().isRowSelected(row);
	}
	
	/**
	 * @return true if Add Button is visible
	 */
	public final boolean isVisibleAdd() {
	
		return getHeaderBar().isVisibleAdd();
	}
	
	/**
	 * @return true if Auto Resize Columns Button is visible
	 */
	public final boolean isVisibleAutoResizeColumns() {
	
		return getHeaderBar().getBtnAutoResizeColumns().isVisible();
	}
	
	/**
	 * @return true if Edit Button is visible
	 */
	public final boolean isVisibleEdit() {
	
		return getHeaderBar().isVisibleEdit();
	}
	
	/**
	 * @return true if Export Button is visible
	 */
	public final boolean isVisibleExport() {
	
		return getHeaderBar().getBtnExport().isVisible();
	}
	
	/**
	 * @return true if Filter Button is visible
	 */
	public final boolean isVisibleFilter() {
	
		return getHeaderBar().getBtnFilter().isVisible();
	}
	
	/**
	 * @return true if Print Button is visible
	 */
	public final boolean isVisiblePrint() {
	
		return getHeaderBar().getBtnPrint().isVisible();
	}
	
	/**
	 * @return true if Remove Button is visible
	 */
	public final boolean isVisibleRemove() {
	
		return getHeaderBar().isVisibleRemove();
	}
	
	/**
	 *
	 */
	public final synchronized void justifyColumnsSize() {
	
		getTable().justifyColumnsSize();
	}
	
	/**
	 *
	 */
	public final void locked() {
	
		getTable().locked();
	}
	
	/**
	 * @param column
	 * @param targetColumn
	 */
	public final void moveColumn(final int column, final int targetColumn) {
	
		getTable().moveColumn(column, targetColumn);
	}
	
	/**
	 * @param tableModelEvent
	 */
	public final void newDataAvailable(final TableModelEvent tableModelEvent) {
	
		getTable().newDataAvailable(tableModelEvent);
	}
	
	/**
	 * @param tableModelEvent
	 */
	public final void newRowsAdded(final TableModelEvent tableModelEvent) {
	
		getTable().newRowsAdded(tableModelEvent);
	}
	
	/**
	 * @param editor
	 * @param row
	 * @param column
	 * @return the Component being edited
	 */
	public final Component prepareEditor(final TableCellEditor editor, final int row, final int column) {
	
		return getTable().prepareEditor(editor, row, column);
	}
	
	/**
	 * @param renderer
	 * @param row
	 * @param column
	 * @return the Component under the event location
	 */
	public final Component prepareRenderer(final TableCellRenderer renderer, final int row, final int column) {
	
		return getTable().prepareRenderer(renderer, row, column);
	}
	
	/**
	 * @return true, unless printing is cancelled by the user
	 * @throws PrinterException
	 */
	public final boolean print() throws PrinterException {
	
		return getTable().print();
	}
	
	/**
	 * @param printMode
	 * @return true, unless printing is cancelled by the user
	 * @throws PrinterException
	 */
	public final boolean print(final PrintMode printMode) throws PrinterException {
	
		return getTable().print(printMode);
	}
	
	/**
	 * @param printMode
	 * @param headerFormat
	 * @param footerFormat
	 * @throws PrinterException
	 */
	public final void print(final PrintMode printMode, final MessageFormat headerFormat, final MessageFormat footerFormat) throws PrinterException {
	
		getTable().print(printMode, headerFormat, footerFormat);
	}
	
	/**
	 * @param printMode
	 * @param headerFormat
	 * @param footerFormat
	 * @param showPrintDialog
	 * @param attr
	 * @param interactive
	 * @return true, unless printing is cancelled by the user
	 * @throws PrinterException
	 * @throws HeadlessException
	 */
	public final boolean print(final PrintMode printMode, final MessageFormat headerFormat, final MessageFormat footerFormat, final boolean showPrintDialog, final PrintRequestAttributeSet attr, final boolean interactive) throws PrinterException, HeadlessException {
	
		return getTable().print(printMode, headerFormat, footerFormat, showPrintDialog, attr, interactive);
	}
	
	/**
	 * @param printMode
	 * @param headerFormat
	 * @param footerFormat
	 * @param showPrintDialog
	 * @param attr
	 * @param interactive
	 * @param service
	 * @return true, unless printing is cancelled by the user
	 * @throws PrinterException
	 * @throws HeadlessException
	 */
	public final boolean print(final PrintMode printMode, final MessageFormat headerFormat, final MessageFormat footerFormat, final boolean showPrintDialog, final PrintRequestAttributeSet attr, final boolean interactive, final PrintService service) throws PrinterException, HeadlessException {
	
		return getTable().print(printMode, headerFormat, footerFormat, showPrintDialog, attr, interactive, service);
	}
	
	/**
	 * @param aColumn
	 */
	public final void removeColumn(final TableColumn aColumn) {
	
		getTable().removeColumn(aColumn);
	}
	
	/**
	 * @param index0
	 * @param index1
	 */
	public final void removeColumnSelectionInterval(final int index0, final int index1) {
	
		getTable().removeColumnSelectionInterval(index0, index1);
	}
	
	/**
	 *
	 */
	public final void removeEditor() {
	
		getTable().removeEditor();
	}
	
	/**
	 *
	 */
	public final void removeNotifyBeanTable() {
	
		getTable().removeNotify();
	}
	
	/**
	 * @param bean
	 */
	public final void removeRow(final Bean bean) {
	
		getTable().removeRow(bean);
		
		configureNewRow();
	}
	
	/**
	 * @param rowIndex
	 */
	public final void removeRow(final int rowIndex) {
	
		getTable().removeRow(rowIndex);
		
		configureNewRow();
	}
	
	/**
	 * @param index0
	 * @param index1
	 */
	public final void removeRowSelectionInterval(final int index0, final int index1) {
	
		getTable().removeRowSelectionInterval(index0, index1);
		
		configureNewRow();
	}
	
	/**
	 *
	 */
	public final void removeSelectedRows() {
	
		final List<Bean> selectedBeans = getSelectedBeans();
		
		//
		for(final Bean bean : selectedBeans) {
			
			removeRow(bean);
		}
		
		configureNewRow();
	}
	
	/**
	 * @param point
	 * @return the index of the row that point lies in, or -1 if the result is not in the range [0, getRowCount()-1]
	 */
	public final int rowAtPoint(final Point point) {
	
		return getTable().rowAtPoint(point);
	}
	
	/**
	 * @param tableModelEvent
	 */
	public final void rowsRemoved(final TableModelEvent tableModelEvent) {
	
		getTable().rowsRemoved(tableModelEvent);
	}
	
	/**
	 * @param rowIndex
	 * @param columnIndex
	 */
	public final void scrollToVisible(final int rowIndex, final int columnIndex) {
	
		getTable().scrollToVisible(rowIndex, columnIndex);
	}
	
	/**
	 *
	 */
	public final void selectAll() {
	
		getTable().selectAll();
		
		getHeaderBar().getBtnEdit().setEnabled(getSelectedRows().length > 0);
		getHeaderBar().getBtnRemove().setEnabled(getSelectedRows().length > 0);
	}
	
	/**
	 * @param acceptDuplicateRows
	 *        the acceptDuplicateRows to set
	 */
	public final void setAcceptDuplicateRows(final boolean acceptDuplicateRows) {
	
		getModel().setAcceptDuplicateRows(acceptDuplicateRows);
	}
	
	/**
	 * @param actionAdd
	 */
	public final void setActionAdd(ActionListener actionAdd) {
		
		getHeaderBar().setActionAdd(actionAdd);;
	}
	
	/**
	 * @param actionEdit
	 */
	public final void setActionEdit(ActionListener actionEdit) {
		
		getHeaderBar().setActionEdit(actionEdit);;
	}
	
	/**
	 * @param actionExport
	 */
	public final void setActionExport(ActionListener actionExport) {
		
		getHeaderBar().setActionExport(actionExport);;
	}
	
	/**
	 * @param actionFind
	 */
	public final void setActionFind(ActionListener actionFind) {
		
		getHeaderBar().setActionFind(actionFind);;
	}
	
	/**
	 * @param actionPrint
	 */
	public final void setActionPrint(ActionListener actionPrint) {
		
		getHeaderBar().setActionPrint(actionPrint);;
	}
	
	/**
	 * @param actionRemove
	 */
	public final void setActionRemove(ActionListener actionRemove) {
		
		getHeaderBar().setActionRemove(actionRemove);;
	}
	
	@Override
	public final void setAtributte(final boolean atributte) {
	
		getTable().setAtributte(atributte);
	}
	
	/**
	 * @param autoCreateColumnsFromModel
	 */
	public final void setAutoCreateColumnsFromModel(final boolean autoCreateColumnsFromModel) {
	
		getTable().setAutoCreateColumnsFromModel(autoCreateColumnsFromModel);
	}
	
	/**
	 * @param autoCreateRowSorter
	 */
	public final void setAutoCreateRowSorter(final boolean autoCreateRowSorter) {
	
		getTable().setAutoCreateRowSorter(autoCreateRowSorter);
	}
	
	/**
	 * @param value
	 */
	public final void setAutoResizeColumns(final boolean value) {
	
		getHeaderBar().setAutoResizeColumns(value);
	}
	
	/**
	 * @return autoResizeColumns
	 */
	public final boolean getAutoResizeColumns() {
	
		return getHeaderBar().getAutoResizeColumns();
	}
	
	/**
	 * @param mode
	 */
	public final void setAutoResizeMode(final int mode) {
	
		getTable().setAutoResizeMode(mode);
	}
	
	/**
	 * @param anEditor
	 */
	public final void setCellEditor(final TableCellEditor anEditor) {
	
		getTable().setCellEditor(anEditor);
	}
	
	/**
	 * @param cellSelectionEnabled
	 */
	public final void setCellSelectionEnabled(final boolean cellSelectionEnabled) {
	
		getTable().setCellSelectionEnabled(cellSelectionEnabled);
	}
	
	/**
	 * @param columnIndex
	 * @param columnAlias
	 */
	public final void setColumnAlias(final int columnIndex, final String columnAlias) {
	
		getTable().setColumnAlias(columnIndex, columnAlias);
	}
	
	/**
	 * @param columnName
	 * @param columnAlias
	 */
	public final void setColumnAlias(final String columnName, final String columnAlias) {
	
		getTable().setColumnAlias(columnName, columnAlias);
	}
	
	/**
	 * @param columnIndex
	 * @param editable
	 */
	public final void setColumnEditable(final int columnIndex, final boolean editable) {
	
		getTable().setColumnEditable(columnIndex, editable);
	}
	
	/**
	 * @param columnIndex
	 * @param maxWidth
	 */
	public final void setColumnMaxWidth(final int columnIndex, final int maxWidth) {
	
		getTable().setColumnMaxWidth(columnIndex, maxWidth);
	}
	
	/**
	 * @param columnIndex
	 * @param minWidth
	 */
	public final void setColumnMinWidth(final int columnIndex, final int minWidth) {
	
		getTable().setColumnMinWidth(columnIndex, minWidth);
	}
	
	/**
	 * @param columnModel
	 */
	public final void setColumnModel(final TableColumnModel columnModel) {
	
		getTable().setColumnModel(columnModel);
	}
	
	/**
	 * @param columnIndex
	 * @param preferredWidth
	 */
	public final void setColumnPreferredWidth(final int columnIndex, final int preferredWidth) {
	
		getTable().setColumnPreferredWidth(columnIndex, preferredWidth);
	}
	
	/**
	 * @param columnSelectionAllowed
	 */
	public final void setColumnSelectionAllowed(final boolean columnSelectionAllowed) {
	
		getTable().setColumnSelectionAllowed(columnSelectionAllowed);
	}
	
	/**
	 * @param index0
	 * @param index1
	 */
	public final void setColumnSelectionInterval(final int index0, final int index1) {
	
		getTable().setColumnSelectionInterval(index0, index1);
	}
	
	/**
	 * @param visible
	 * @param columnIndexes
	 */
	public final void setColumnVisible(final boolean visible, final int... columnIndexes) {
	
		getTable().setColumnVisible(visible, columnIndexes);
	}
	
	/**
	 * @param visible
	 * @param columnNames
	 */
	public final void setColumnVisible(final boolean visible, final String... columnNames) {
	
		getTable().setColumnVisible(visible, columnNames);
	}
	
	/**
	 * @param columnIndex
	 * @param visible
	 */
	public final void setColumnVisible(final int columnIndex, final boolean visible) {
	
		getTable().setColumnVisible(columnIndex, visible);
	}
	
	/**
	 * @param columnName
	 * @param visible
	 */
	public final void setColumnVisible(final String columnName, final boolean visible) {
	
		getTable().setColumnVisible(columnName, visible);
	}
	
	/**
	 * @param visible
	 * @param columnAlias
	 */
	public final void setColumnVisibleByAlias(final boolean visible, final String... columnAlias) {
	
		getTable().setColumnVisibleByAlias(visible, columnAlias);
	}
	
	/**
	 * @param columnAlias
	 * @param visible
	 */
	public final void setColumnVisibleByAlias(final String columnAlias, final boolean visible) {
	
		getTable().setColumnVisibleByAlias(columnAlias, visible);
	}
	
	/**
	 * @param columnIndex
	 * @param width
	 */
	public final void setColumnWidth(final int columnIndex, final int width) {
	
		getTable().setColumnWidth(columnIndex, width);
	}
	
	/**
	 * @param columnClass
	 * @param editor
	 */
	public final void setDefaultEditor(final Class<?> columnClass, final TableCellEditor editor) {
	
		getTable().setDefaultEditor(columnClass, editor);
	}
	
	/**
	 * @param columnClass
	 * @param renderer
	 */
	public final void setDefaultRenderer(final Class<?> columnClass, final TableCellRenderer renderer) {
	
		getTable().setDefaultRenderer(columnClass, renderer);
	}
	
	/**
	 * @param dragEnabled
	 */
	public final void setDragEnabled(final boolean dragEnabled) {
	
		getTable().setDragEnabled(dragEnabled);
	}
	
	/**
	 * @param columnIndex
	 */
	public final void setEditingColumn(final int columnIndex) {
	
		getTable().setEditingColumn(columnIndex);
	}
	
	/**
	 * @param rowIndex
	 */
	public final void setEditingRow(final int rowIndex) {
	
		getTable().setEditingRow(rowIndex);
	}
	
	/**
	 * @param enabled
	 */
	public final void setEnabledAutoResizeColumns(final boolean enabled) {
	
		getHeaderBar().setEnabledAutoResizeColumns(enabled);
	}
	
	/**
	 * @param enabled
	 */
	public final void setEnabledClearFilter(final boolean enabled) {
	
		getHeaderBar().setEnabledClearFilter(enabled);
	}
	
	/**
	 * @param enabled
	 */
	public final void setEnabledCrudButtons(final boolean enabled) {
	
		getHeaderBar().setEnabledCrudButtons(enabled);
	}
	
	/**
	 * @param enabled
	 */
	public final void setEnabledExport(final boolean enabled) {
	
		getHeaderBar().setEnabledExport(enabled);
	}
	
	/**
	 * @param enabled
	 */
	public final void setEnabledFilter(final boolean enabled) {
	
		getHeaderBar().setEnabledFilter(enabled);
	}
	
	/**
	 * @param enabled
	 */
	public final void setEnabledPrint(final boolean enabled) {
	
		getHeaderBar().setEnabledPrint(enabled);
	}
	
	/**
	 * @param enabled
	 */
	public final void setEnabledTools(final boolean enabled) {
	
		getHeaderBar().setEnabledTools(enabled);
	}
	
	/**
	 * @param fillsViewportHeight
	 */
	public final void setFillsViewportHeight(final boolean fillsViewportHeight) {
	
		getTable().setFillsViewportHeight(fillsViewportHeight);
	}
	
	/**
	 * @param gridColor
	 */
	public final void setGridColor(final Color gridColor) {
	
		getTable().setGridColor(gridColor);
	}
	
	@Override
	public final void setIndex(final int index) {
	
		getTable().setIndex(index);
	}
	
	/**
	 * @param intercellSpacing
	 */
	public final void setIntercellSpacing(final Dimension intercellSpacing) {
	
		getTable().setIntercellSpacing(intercellSpacing);
	}
	
	/**
	 * @param tableModel
	 */
	public final void setModel(final BeanTableModel<Bean> tableModel) {
	
		getTable().setModel(tableModel);
		
		clearFilter();
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see java.awt.Component#setName(java.lang.String)
	 */
	@Override
	public final void setName(final String name) {
	
		super.setName(name);
		
		getTable().setName(name);
		
		setRequired(isRequired());
	}
	
	/**
	 * @param size
	 */
	public final void setPreferredScrollableViewportSize(final Dimension size) {
	
		getTable().setPreferredScrollableViewportSize(size);
	}
	
	@Override
	public final void setRequired(final boolean required) {
	
		getTable().setRequired(required);
		
		//
		if(required) {
			
			//
			if(isRequiredBorderEnabled()) {
				
				setBorder(new LineBorder(Color.RED));
			}
			
			//
			if(CheckUtil.isNullOrAbsoluteEmpty(getName())) {
				
				setToolTipText(I18N.component().requiredThis());
				
			}else {
				
				setToolTipText(I18N.component().requiredField(getName()));
			}
			
		}else {
			
			setBorder(UIManager.getBorder("Panel.border"));
			setToolTipText(null);
		}
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see org.jxSwing.component.JXComponent#setRequiredBorderEnabled(boolean)
	 */
	@Override
	public final void setRequiredBorderEnabled(final boolean requiredBorderEnabled) {
	
		this.requiredBorderEnabled = requiredBorderEnabled;
	}
	
	/**
	 * @param rowIndex
	 * @param editable
	 */
	public final void setRowEditable(final int rowIndex, final boolean editable) {
	
		getTable().setRowEditable(rowIndex, editable);
	}
	
	/**
	 * @param rowHeight
	 */
	public final void setRowHeight(final int rowHeight) {
	
		getTable().setRowHeight(rowHeight);
	}
	
	/**
	 * @param row
	 * @param rowHeight
	 */
	public final void setRowHeight(final int row, final int rowHeight) {
	
		getTable().setRowHeight(row, rowHeight);
	}
	
	/**
	 * @param rowMargin
	 */
	public final void setRowMargin(final int rowMargin) {
	
		getTable().setRowMargin(rowMargin);
	}
	
	/**
	 * @param beans
	 */
	public final void setRows(final Bean[] beans) {
	
		setRows(Arrays.asList(beans));
	}
	
	/**
	 * @param beans
	 */
	public final void setRows(final Collection<Bean> beans) {
	
		getTable().setRows(beans);
		
		configureNewRow();
	}
	
	/**
	 * @param rowSelectionAllowed
	 */
	public final void setRowSelectionAllowed(final boolean rowSelectionAllowed) {
	
		getTable().setRowSelectionAllowed(rowSelectionAllowed);
		
		getHeaderBar().getBtnEdit().setEnabled(getSelectedRows().length > 0);
		getHeaderBar().getBtnRemove().setEnabled(getSelectedRows().length > 0);
	}
	
	/**
	 * @param index0
	 * @param index1
	 */
	public final void setRowSelectionInterval(final int index0, final int index1) {
	
		getTable().setRowSelectionInterval(index0, index1);
		
		getHeaderBar().getBtnEdit().setEnabled(getSelectedRows().length > 0);
		getHeaderBar().getBtnRemove().setEnabled(getSelectedRows().length > 0);
	}
	
	/**
	 * @param sorter
	 */
	public final void setRowSorter(final RowSorter<? extends BeanTableModel<Bean>> sorter) {
	
		getTable().setRowSorter(sorter);
		
		clearFilter();
	}
	
	/**
	 * @param columnIndex
	 */
	public final void setSelectedColumn(final int columnIndex) {
	
		getTable().setSelectedColumn(columnIndex);
	}
	
	/**
	 * @param columnIndexes
	 */
	public final void setSelectedColumns(final int... columnIndexes) {
	
		getTable().setSelectedColumns(columnIndexes);
	}
	
	/**
	 * @param rowIndex
	 */
	public final void setSelectedRow(final int rowIndex) {
	
		getTable().setSelectedRow(rowIndex);
		
		getHeaderBar().getBtnEdit().setEnabled(getSelectedRows().length > 0);
		getHeaderBar().getBtnRemove().setEnabled(getSelectedRows().length > 0);
	}
	
	/**
	 * @param rowIndexes
	 */
	public final void setSelectedRows(final int... rowIndexes) {
	
		getTable().setSelectedRows(rowIndexes);
		
		getHeaderBar().getBtnEdit().setEnabled(getSelectedRows().length > 0);
		getHeaderBar().getBtnRemove().setEnabled(getSelectedRows().length > 0);
	}
	
	/**
	 * @param selectionBackground
	 */
	public final void setSelectionBackground(final Color selectionBackground) {
	
		getTable().setSelectionBackground(selectionBackground);
	}
	
	/**
	 * @param selectionForeground
	 */
	public final void setSelectionForeground(final Color selectionForeground) {
	
		getTable().setSelectionForeground(selectionForeground);
	}
	
	/**
	 * @param selectionMode
	 */
	public final void setSelectionMode(final int selectionMode) {
	
		getTable().setSelectionMode(selectionMode);
	}
	
	/**
	 * @param newModel
	 */
	public final void setSelectionModel(final ListSelectionModel newModel) {
	
		getTable().setSelectionModel(newModel);
	}
	
	/**
	 * @param showGrid
	 */
	public final void setShowGrid(final boolean showGrid) {
	
		getTable().setShowGrid(showGrid);
	}
	
	/**
	 * @param showHorizontalLines
	 */
	public final void setShowHorizontalLines(final boolean showHorizontalLines) {
	
		getTable().setShowHorizontalLines(showHorizontalLines);
	}
	
	/**
	 * @param showVerticalLines
	 */
	public final void setShowVerticalLines(final boolean showVerticalLines) {
	
		getTable().setShowVerticalLines(showVerticalLines);
	}
	
	/**
	 * @param sizeToDialog
	 */
	public final void setSizeToDialogInBeanEditor(final Dimension sizeToDialog) {
	
		getTable().setSizeToDialogInBeanEditor(sizeToDialog);
	}
	
	/**
	 * @param surrendersFocusOnKeystroke
	 */
	public final void setSurrendersFocusOnKeystroke(final boolean surrendersFocusOnKeystroke) {
	
		getTable().setSurrendersFocusOnKeystroke(surrendersFocusOnKeystroke);
	}
	
	/**
	 * @param tableHeader
	 */
	public final void setTableHeader(final JTableHeader tableHeader) {
	
		getTable().setTableHeader(tableHeader);
	}
	
	/**
	 * @param tableTitle
	 */
	public final void setTitle(final String tableTitle) {
	
		getHeaderBar().setTitle(tableTitle);
	}
	
	/**
	 * @param ui
	 */
	public final void setUIBeanTable(final TableUI ui) {
	
		getTable().setUI(ui);
	}
	
	/**
	 * @param update
	 */
	public final void setUpdateSelectionOnSort(final boolean update) {
	
		getTable().setUpdateSelectionOnSort(update);
	}
	
	/**
	 * @param aValue
	 * @param row
	 * @param column
	 */
	public final void setValueAt(final Object aValue, final int row, final int column) {
	
		getTable().setValueAt(aValue, row, column);
	}
	
	/**
	 * @param visible
	 */
	public final void setVisibleAutoResizeColumns(final boolean visible) {
	
		getHeaderBar().setVisibleAutoResizeColumns(visible);
	}
	
	/**
	 * @param visible
	 */
	public final void setVisibleClearFilter(final boolean visible) {
	
		getHeaderBar().setVisibleClearFilter(visible);
	}
	
	/**
	 * @param visible
	 */
	public final void setVisibleCrudButtons(final boolean visible) {
		
		getHeaderBar().setVisibleCrudButtons(visible);
	}
	
	/**
	 * @param visibleAdd
	 * @param visibleEdit
	 * @param visibleRemove
	 */
	public final void setVisibleCrudButtons(final boolean visibleAdd, final boolean visibleEdit, final boolean visibleRemove) {
	
		getHeaderBar().setVisibleCrudButtons(visibleAdd, visibleEdit, visibleRemove);
	}
	
	/**
	 * @param visible
	 */
	public final void setVisibleExport(final boolean visible) {
	
		getHeaderBar().setVisibleExport(visible);
	}
	
	/**
	 * @param visible
	 */
	public final void setVisibleFilter(final boolean visible) {
	
		getHeaderBar().setVisibleFilter(visible);
	}
	
	/**
	 * @param value
	 */
	public final void setVisibleFooterBar(final boolean value) {
	
		getFooterBar().setVisible(value);
	}
	
	/**
	 * @param value
	 */
	public final void setVisibleHeaderBar(final boolean value) {
	
		getHeaderBar().setVisible(value);
	}
	
	/**
	 * @param visible
	 */
	public final void setVisiblePrint(final boolean visible) {
	
		getHeaderBar().setVisiblePrint(visible);
	}
	
	/**
	 * @param visible
	 */
	public final void setVisibleTools(final boolean visible) {
	
		getHeaderBar().setVisibleTools(visible);
	}
	
	/**
	 * @return the showLineNumber
	 */
	public final boolean showLineNumber() {
	
		return getTable().showLineNumber();
	}
	
	/**
	 * @param showLineNumber
	 */
	public final void showLineNumber(final boolean showLineNumber) {
	
		getTable().showLineNumber(showLineNumber);
		
		//
		if(showLineNumber) {
			
			getScrollPane().setRowHeaderView(new LineNumberTable(getScrollPane(), getTable()));
			
		}else {
			
			getScrollPane().setRowHeaderView(null);
		}
	}
	
	/**
	 *
	 */
	public final void showOnlyHorizontalGridLines() {
	
		getTable().showOnlyHorizontalGridLines();
	}
	
	/**
	 *
	 */
	public final void showOnlyVerticalGridLines() {
	
		getTable().showOnlyVerticalGridLines();
	}
	
	/**
	 * @param resizingColumn
	 */
	public final void sizeColumnsToFit(final int resizingColumn) {
	
		getTable().sizeColumnsToFit(resizingColumn);
	}
	
	/**
	 * @param columnIndex
	 */
	public final void sorter(final int columnIndex) {
	
		getTable().sorter(columnIndex);
	}
	
	/**
	 * @param columnAlias
	 */
	public final void sorter(final String columnAlias) {
	
		getTable().sorter(columnAlias);
	}
	
	/**
	 * @param rowSorterEvent
	 */
	public final void sorterChanged(final RowSorterEvent rowSorterEvent) {
	
		getTable().sorterChanged(rowSorterEvent);
	}
	
	/**
	 * @param tableModelEvent
	 */
	public final void tableChanged(final TableModelEvent tableModelEvent) {
	
		getTable().tableChanged(tableModelEvent);
	}
	
	/**
	 * exportInvisibleColumns = false
	 * 
	 * @return csv String
	 * @throws IOException
	 */
	public final String toCSV() throws IOException {
	
		return getTable().toCSV();
	}
	
	/**
	 * @param exportInvisibleColumns
	 * @return csv String
	 * @throws IOException
	 */
	public final String toCSV(final boolean exportInvisibleColumns) throws IOException {
	
		return getTable().toCSV(exportInvisibleColumns);
	}
	
	/**
	 * exportInvisibleColumns = false
	 * 
	 * @param separator
	 * @return csv String
	 * @throws IOException
	 */
	public final String toCSV(final CSVSeparator separator) throws IOException {
	
		return getTable().toCSV(separator);
	}
	
	/**
	 * @param separator
	 * @param exportInvisibleColumns
	 * @return csv String
	 * @throws IOException
	 */
	public final String toCSV(final CSVSeparator separator, final boolean exportInvisibleColumns) throws IOException {
	
		return getTable().toCSV(separator, exportInvisibleColumns);
	}
	
	/**
	 * exportInvisibleColumns = false
	 * 
	 * @param csvFile
	 * @param separator
	 * @throws IOException
	 */
	public final void toCSV(final File csvFile, final CSVSeparator separator) throws IOException {
	
		getTable().toCSV(csvFile, separator);
	}
	
	/**
	 * @param csvFile
	 * @param separator
	 * @param exportInvisibleColumns
	 * @throws IOException
	 */
	public final void toCSV(final File csvFile, final CSVSeparator separator, final boolean exportInvisibleColumns) throws IOException {
	
		getTable().toCSV(csvFile, separator, exportInvisibleColumns);
	}
	
	/**
	 * @param gifFile
	 * @throws IOException
	 */
	public final void toGIF(final File gifFile) throws IOException {
	
		getTable().toGIF(gifFile);
	}
	
	/**
	 * exportInvisibleColumns = false
	 * 
	 * @param htmlFile
	 * @throws IOException
	 * @throws ImageFormatException
	 */
	public final void toHTML(final File htmlFile) throws IOException, ImageFormatException {
	
		getTable().toHTML(htmlFile);
	}
	
	/**
	 * @param htmlFile
	 * @param exportInvisibleColumns
	 * @throws IOException
	 * @throws ImageFormatException
	 */
	public final void toHTML(final File htmlFile, final boolean exportInvisibleColumns) throws IOException, ImageFormatException {
	
		getTable().toHTML(htmlFile, exportInvisibleColumns);
	}
	
	/**
	 * @return bufferedImage
	 * @throws IOException
	 */
	public final BufferedImage toImage() throws IOException {
	
		return getTable().toImage();
	}
	
	/**
	 * @param jpgFile
	 * @throws IOException
	 */
	public final void toJPG(final File jpgFile) throws IOException {
	
		getTable().toJPG(jpgFile);
	}
	
	/**
	 * @return json String
	 */
	public final String toJSON() {
	
		return getTable().toJSON();
	}
	
	/**
	 * @param jsonFile
	 * @throws IOException
	 */
	public final void toJSON(final File jsonFile) throws IOException {
	
		getTable().toJSON(jsonFile);
	}
	
	/**
	 * @param pngFile
	 * @throws IOException
	 */
	public final void toPNG(final File pngFile) throws IOException {
	
		getTable().toPNG(pngFile);
	}
	
	/**
	 * exportInvisibleColumns = false
	 * 
	 * @param xlsFile
	 * @throws Throwable
	 */
	public final void toXLS(final File xlsFile) throws Throwable {
	
		getTable().toXLS(getTitle(), xlsFile);
	}
	
	/**
	 * @param xlsFile
	 * @param exportInvisibleColumns
	 * @throws Throwable
	 */
	public final void toXLS(final File xlsFile, final boolean exportInvisibleColumns) throws Throwable {
	
		getTable().toXLS(getTitle(), xlsFile, exportInvisibleColumns);
	}
	
	/**
	 * @return xml String
	 */
	public final String toXML() {
	
		return getTable().toXML();
	}
	
	/**
	 * @param xmlFile
	 * @throws IOException
	 */
	public final void toXML(final File xmlFile) throws IOException {
	
		getTable().toXML(xmlFile);
	}
	
	/**
	 *
	 */
	public final void unLocked() {
	
		getTable().unLocked();
	}
	
	/**
	 * @param listSelectionEvent
	 */
	public final void valueChanged(final ListSelectionEvent listSelectionEvent) {
	
		getTable().valueChanged(listSelectionEvent);
	}
}
